/* Copyright(C): Leaf Johnson 2009,2010

    This file is part of leaf-lib.

    leaf-lib is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    leaf-lib is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with leaf-lib.  If not, see <http://www.gnu.org/licenses/>.


 * 
 * 
 */


#include <leaf/vector.h>
#include <stdlib.h>
#include <string.h>

/*初始化Vector，分配数据空间*/
void vectorInit(Vector *v, size_t bufSize){
	if(bufSize <= 0){
		v->capacity = 0;
		v->data = NULL;
	}
	else{
		v->data = (VectorDataType *)malloc(bufSize * sizeof(VectorDataType));
		if( v->data != NULL)
			v->capacity = bufSize;
	}
}

/*释放数据空间*/
void vectorFree(Vector *v){
	if(v->data != NULL && v->capacity > 0){
		free(v->data);
	}
	v->data = NULL;
	v->capacity = 0;
}

/*设置某一位上的数据，如果空间不足，会扩展空间，如果无法分配空间，则直接返回*/
inline void vectorSet(Vector *v, size_t idx, VectorDataType data){
	if(idx >= v->capacity){
		if( vectorExtends(v, idx + VECTOR_SIZE_INC) <= idx )
			return;
	}
	v->data[idx] = data;

}

/*取得某一位上的数据*/
inline VectorDataType vectorGet(const Vector *v, size_t idx){
	if( idx >= v->capacity ){//不返回没有初始化的数据
		return 0;
	}
	return(v->data[idx]);
}

/*扩展数据空间*/
int  vectorExtends(Vector *v, size_t size){
	void *newarea;
	if(size < v->capacity){
		return v->capacity;
	}
	newarea = realloc(v->data, size);
	if( newarea == NULL )
		return v->capacity;

	v->data = (VectorDataType *)newarea;
	v->capacity = size;
	return size;
}

/*写入数据串，如果空间不足，会扩展空间*/
int  vectorWrite(Vector *v, size_t idx, const VectorDataType *buf, size_t len){
	if( idx + len > v->capacity ){
		if( vectorExtends( v, idx + len + VECTOR_SIZE_INC ) <= idx + len )
		{
			len = v->capacity - idx;
		}
	}
	memcpy(&(v->data[idx]), buf, len);
	return len;
}

/*读出数据串，如果遇到结尾，则停止，返回实际读出的数据数*/
int  vectorRead(const Vector *v, size_t idx,  VectorDataType *buf, size_t len){
	if( idx + len > v->capacity ){
		len = v->capacity - idx;
	}
	memcpy(buf, &(v->data[idx]), len);
	return len;
}

/*从另一个Vector中指定位置开始，拷贝指定长度的数据，到另一向量中指定位置*/
inline int  vectorCopy(Vector *src, size_t srcidx, Vector *dest, size_t destidx, size_t len){
	return vectorWrite(dest, destidx, &(src->data[srcidx]), len);
}

/*获得缓冲区地址*/
void *vectorGetBuffer(Vector *vec, size_t idx){
	return (&vec->data[idx]);
}


